package com.dctp.ems.controller;

import com.dctp.common.controller.BaseController;
import com.dctp.common.utils.DateUtil;
import com.dctp.common.vo.JsonResult;
import com.jfinal.aop.Before;
import com.jfinal.core.Path;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色管理
 *
 * basePath: /role
 */
@Path("/role")
public class EmsRoleController extends BaseController {

    /**
     * GET /role/list
     * <p>
     * 分页查询角色
     * </p>
     * query: page | pageSize | name | code | role | status
     */
    public void list() {

        int page = getInt("currentPage", 1);
        int pageSize = getInt("pageSize", 10);
        String name = getPara("name", "");
        String code = getPara("code", "");
        String role = getPara("role", "");
        String status = getPara("status", "");

        StringBuilder where = new StringBuilder(" WHERE 1=1 ");
        List<Object> ps = new ArrayList<>();
        if (StrKit.notBlank(name)) {
            where.append("AND name LIKE ? ");
            ps.add('%' + name + '%');
        }
        if (StrKit.notBlank(code)) {
            where.append("AND code LIKE ? ");
            ps.add('%' + code + '%');
        }
        if (StrKit.notBlank(role)) {
            where.append("AND role LIKE ? ");
            ps.add('%' + role + '%');
        }
        if (StrKit.notBlank(status)) {
            where.append("AND status = ? ");
            ps.add(status);
        }

        var p = Db.paginate(page, pageSize,
                "SELECT * ",
                "FROM card_enterprise_role " + where + " ORDER BY id ASC",
                ps.toArray());
        p.getList().forEach(r -> r.set("create_time",
                r.getLocalDateTime("create_time").toString().replace('T', ' ')));
        renderJson(JsonResult.successWithData(
            new com.dctp.common.vo.PageResult<>(p.getList(), p.getTotalRow(), pageSize, page)
        ));
    }

    /**
     * POST /role/add
     * <p>
     * 新增角色
     * </p>
     * body: name, role, ...
     */
    @Before(Tx.class)
    public void add() {
        Record body = jsonBody();
        if (StrKit.isBlank(body.getStr("name")) || StrKit.isBlank(body.getStr("role"))) {
            renderJson(JsonResult.failWithMessage("name 与 role 均不能为空"));
            return;
        }
        body.set("create_time", DateUtil.now());
        if (!Db.save("card_enterprise_role", body))
            throw new RuntimeException("新增角色失败");
        renderJson(JsonResult.success());
    }

    /**
     * POST /role/update/:id
     * <p>
     * 修改角色信息
     * </p>
     */
    @Before(Tx.class)
    public void update() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }

        Record body = jsonBody();
        if (body.getColumns().isEmpty()) {
            renderJson(JsonResult.failWithMessage("无有效字段"));
            return;
        }

        body.set("id", id)
                .set("update_time", new Timestamp(System.currentTimeMillis()));

        if (!Db.update("card_enterprise_role", body))
            throw new RuntimeException("角色不存在或已被删除");

        renderJson(JsonResult.success());
    }

    /**
     * POST /role/delete/:id
     * <p>
     * 删除角色及其关联关系
     * </p>
     */
    @Before(Tx.class)
    public void delete() {
        Long id = getParaToLong(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }

        Db.update("DELETE FROM card_enterprise_admin_role WHERE role_id=?", id);
        Db.update("DELETE FROM card_enterprise_role_menu  WHERE role_id=?", id);
        int rows = Db.update("DELETE FROM card_enterprise_role WHERE id=?", id);
        if (rows == 0)
            throw new RuntimeException("角色不存在或已删除");

        renderJson(JsonResult.success());
    }

    /**
     * GET /role/menu/:id
     * <p>
     * 获取指定角色已配置的菜单 ID + 当前用户拥有的菜单列表
     * </p>
     */
    public void menu() {
        Long roleId = getParaToLong(0);
        Long selfId = getUserId();
        if (roleId == null || selfId == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }

        List<Integer> roleMenuIds = Db.query(
                "SELECT menu_id FROM card_enterprise_role_menu WHERE role_id=?", roleId);

        List<Integer> selfMenuIds = Db.query(
                "SELECT menu_id FROM card_enterprise_role_menu WHERE role_id=?", selfId);

        List<Kv> selfMenus = List.of();
        if (!selfMenuIds.isEmpty()) {
            String in = String.join(",", Collections.nCopies(selfMenuIds.size(), "?"));
            List<Record> rows = Db.find(
                    "SELECT id,title,parent_id,menu_type FROM card_enterprise_menu WHERE id IN (" + in + ")",
                    selfMenuIds.toArray());
            selfMenus = rows.stream()
                    .map(r -> Kv.create()
                            .set("id", r.getInt("id"))
                            .set("parentId", r.getInt("parent_id"))
                            .set("menuType", r.getInt("menu_type"))
                            .set("title", r.getStr("title")))
                    .collect(Collectors.toList());
        }

        Kv data = Kv.create()
                .set("roleMenuIds", roleMenuIds)
                .set("selfMenus", selfMenus);

        renderJson(JsonResult.successWithData(data));
    }

    /**
     * POST /role/update-menu/:id
     * <p>
     * 重写角色菜单权限
     * </p>
     * body: menuIds[]
     */
    @Before(Tx.class)
    public void updateMenu() {

        Long roleId = getParaToLong(0);
        Record body = jsonBody();
        List<Integer> menuIds = body.get("menuIds", Collections.emptyList());

        if (roleId == null || menuIds == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }

        Db.update("DELETE FROM card_enterprise_role_menu WHERE role_id=?", roleId);

        if (!menuIds.isEmpty()) {
            StringBuilder sql = new StringBuilder(
                    "INSERT INTO card_enterprise_role_menu(role_id,menu_id) VALUES ");
            List<Object> ps = new ArrayList<>();
            for (int i = 0; i < menuIds.size(); i++) {
                sql.append("(?,?)");
                if (i < menuIds.size() - 1)
                    sql.append(',');
                ps.add(roleId);
                ps.add(menuIds.get(i));
            }
            Db.update(sql.toString(), ps.toArray());
        }

        renderJson(JsonResult.success());
    }

    /**
     * GET /role/all
     * <p>
     * 获取所有启用状态的角色
     * </p>
     */
    public void all() {
        List<Record> rows = Db.find("SELECT id,name FROM card_enterprise_role WHERE status=1");
        renderJson(JsonResult.successWithData(rows));
    }
}
